using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.ComponentModel;

namespace NBear.Tools.Configurator
{
    public class ColumnConfiguration
    {
        private string propertyName;
        private string columnName;
        private bool isPrimaryKey;
        private bool isCustomProperty;
        private string[] parameters;
        private string dbType;

        public ColumnConfiguration(string propertyName)
        {
            this.propertyName = propertyName;
        }

        [Category("Main"), Description("Name of property.")]
        public string PropertyName
        {
            get
            {
                return propertyName;
            }
        }

        [Category("Main"), Description("Name of Data Table Column.")]
        public string ColumnName
        {
            get
            {
                return columnName;
            }
            set
            {
                columnName = value;
            }
        }

        [Category("Main"), Description("Is this property a primary key?")]
        public bool IsPrimaryKey
        {
            get
            {
                return isPrimaryKey;
            }
            set
            {
                isPrimaryKey = value;
            }
        }

        [Category("Main"), Description("Is this property a custom property?")]
        public bool IsCustomProperty
        {
            get
            {
                return isCustomProperty;
            }
            set
            {
                isCustomProperty = value;
            }
        }

        [Category("Main"), Description("Parameters used only by custom properties.")]
        public string[] Parameters
        {
            get
            {
                return parameters;
            }
            set
            {
                parameters = value;
            }
        }

        [Category("Main"), Description("The mapping Data Table column's database relevant type.")]
        public string DbType
        {
            get
            {
                return dbType;
            }
            set
            {
                dbType = value;
            }
        }
    }

    public class EntityConfiguration
    {
        private string fullName;
        private string tableName;
        private bool isView = false;
        private string additionalWhere;
        private string additionalInsert;
        private bool isCascadeUpdate = false;
        private bool isContract = false;
        private string updateTableName;
        private string filterColumnName;
        private bool includedInSqlGenerating = true;
        private string storedProcedure;
        private bool storedProcedureFillByIndex;

        public EntityConfiguration(string fullName)
        {
            this.fullName = fullName;
        }

        [Category("Main"), Description("Full name of entity.")]
        public string FullName
        {
            get
            {
                return fullName;
            }
        }

        [Category("Main"), Description("The mapping table name/view or query sql.")]
        public string TableName
        {
            get
            {
                return this.tableName;
            }
            set
            {
                tableName = value;
            }
        }

        [Category("Main"), Description("Is this entity readonly?")]
        public bool IsView
        {
            get
            {
                return this.isView;
            }
            set
            {
                this.isView = value;
            }
        }

        [Category("Main"), Description("When doin updating, update only extended properties to parent entities or not?")]
        public bool IsCascadeUpdate
        {
            get
            {
                return isCascadeUpdate;
            }
            set
            {
                isCascadeUpdate = value;
            }
        }

        [Category("Main"), Description("Is this entity a contract entity. Contract entities only means some contract of property list, a contract entity do not map to any physical table, but means all impelementing entity of a contract entity should contains properties defined in contract entities in it's mapping table.")]
        public bool IsContract
        {
            get
            {
                return isContract;
            }
            set
            {
                isContract = value;
            }
        }

        [Category("Extended"), Description("Additional where statement appended to entity's select, delete or update query")]
        public string AdditionalWhere
        {
            get
            {
                return additionalWhere;
            }
            set
            {
                additionalWhere = value;
            }
        }

        [Category("Extended"), Description("Additional Insert statement appended to entity's insert query.")]
        public string AdditionalInsert
        {
            get
            {
                return additionalInsert;
            }
            set
            {
                additionalInsert = value;
            }
        }

        [Category("Main"), Description("The name of table which is used as the insert/update/delete table when this value is not null, or easily use TableName.")]
        public string UpdateTableName
        {
            get
            {
                if (updateTableName != null)
                {
                    return updateTableName;
                }
                else
                {
                    return this.tableName;
                }
            }
            set
            {
                updateTableName = value;
            }
        }

        [Category("Main"), Description("Include this entity when generating database creation sql script or not.")]
        public bool IncludedInSqlGenerating
        {
            get
            {
                return includedInSqlGenerating && (!IsContract) && (!(IsView && UpdateTableName == null));
            }
            set
            {
                includedInSqlGenerating = value;
            }
        }

        [Category("Extended"), Description("The name of column used to filter rows in the mapping. This column name should be the name of column used in AdditionalWhere and AdditionalInsert properties.")]
        public string FilterColumnName
        {
            get
            {
                return filterColumnName;
            }
            set
            {
                filterColumnName = value;
            }
        }

        [Category("StoredProcedure"), Description("The name of a StoredProcedure binded with this entity.")]
        public string StoredProcedure
        {
            get
            {
                return storedProcedure;
            }
            set
            {
                storedProcedure = value;
            }
        }

        [Category("StoredProcedure"), Description("When filling return data from stored procedure, by column index or column name.")]
        public bool StoredProcedureFillByIndex
        {
            get
            {
                return storedProcedureFillByIndex;
            }
            set
            {
                storedProcedureFillByIndex = value;
            }
        }
    }
}
